package com.xiexiaozhou.helper.api.aspect;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 统一处理web请求日志
 */
@Component
@Aspect
public class HttpAspect {

    /**
     * 使用指定类初始化日志对象
     */
    private Logger logger = LoggerFactory.getLogger(HttpAspect.class);

    /**
     * 定义一个切入点表达式,用来确定哪些类需要代理
     */
    @Pointcut("execution(public * com.xiexiaozhou.helper.api.controller.*.*(..))")
    public void cut() {
    }

    /**
     * 前置方法,在目标方法执行前执行
     *
     * @param joinPoint 封装了代理方法信息的对象,若用不到则可以忽略不写
     */
    @Before("cut()")
    public void doBefore(JoinPoint joinPoint) {
        //在非web控制器层获取request、response等对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        //记录请求的url
        logger.info("url={}", request.getRequestURI());

        //记录请求的method
        logger.info("method={}", request.getMethod());

        //记录请求的ip
        logger.info("ip={}", request.getRemoteAddr());
    }

    /**
     * 在目标方法执行后执行。用于获取返回值
     *
     * @param obj
     * @throws JsonProcessingException
     */
    @AfterReturning(returning = "obj", pointcut = "cut()")
    public void doAfterReturning(Object obj) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        logger.info("response={}", objectMapper.writeValueAsString(obj));
    }
}
